#ifndef _IO_UDP_H_
#define _IO_UDP_H_

#include <ioeventdef.h>
#include <iocontext.hpp>

class IoUdpBase
{
public:
	IoUdpBase() {
		this->ptr = NULL;
		this->safe = NULL;
		s_memset(&this->ctx, 0, sizeof(io_data_t));
	}
	virtual ~IoUdpBase() {
		udp_destory();
	}

public:
	int udp_create(io_service* pService) {

		this->ptr = ALLOC_NEW io_usocket(*pService);
		rc_assert(this->ptr, S_ERROR)

		this->safe = ALLOC_NEW io_strand(*pService);
		rc_assert(this->safe, S_ERROR)

		return S_SUCCESS;
	}
	int udp_destory() {

		rc_assert(this->ptr, S_ERROR)
		delete this->ptr;
		this->ptr = NULL;

		rc_assert(this->safe, S_ERROR)
		delete this->safe;
		this->safe = NULL;

		return S_SUCCESS;
	}
	int udp_assign(_sock_t* s) {

		rc_assert(this->ptr, S_ERROR)

		io_error_code ec;
		this->ptr->assign(boost::asio::ip::udp::v4(), *s, ec);
		rc_assert(!ec, S_ERROR)
		rc_assert(this->ptr->is_open(), S_ERROR)

		return S_SUCCESS;
	}
	int	udp_close() {

		rc_assert(this->ptr, S_ERROR)
		rc_assert(this->ptr->is_open(), S_ERROR)
		int rc = S_SUCCESS;

		try {
			this->ptr->close();
		} catch (stdexcep err) {
			loge("std::exception:%s", err.what());
			rc = S_ERROR;
		}

		return rc;
	}
	int udp_is_open() {

		rc_assert(this->ptr->is_open(), S_ERROR)
		return S_SUCCESS;
	}
	int udp_setoption() {

		rc_assert(this->ptr, S_ERROR)
		int rc = S_SUCCESS;

		try {
			this->ptr->set_option(boost::asio::socket_base::linger(true, 5));
		} catch (stdexcep err) {
			loge("std::exception:%s", err.what());
			rc = S_ERROR;
		}
		return rc;
	}
public:
	io_usocket_ptr		ptr;
	io_strand_ptr		safe;
	io_data_t			ctx;
};

#endif 
